package com.put.mybills.activities;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import com.put.mybills.R;
import com.put.mybills.adapter.GlobalParams;
import com.put.mybills.model.Bill;
import com.put.mybills.model.Facture;
import com.put.mybills.model.TemplateBarcode;
import com.put.mybills.model.Unit;
import comt.put.mybills.zxing.IntentIntegrator;
import comt.put.mybills.zxing.IntentIntegratorV30;
import comt.put.mybills.zxing.IntentResult;
import android.app.ActionBar.LayoutParams;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class NewBillFragment extends Fragment {
	
	private static final String TAG = "NewBillFragment";	

	private EditText newBillName;
	private EditText newBillDescription;
	private EditText newBillPrice;
	private ImageButton newBillBarcode;	
	private ImageButton newBillDatepicker;
	private ImageButton newBillTakePhoto;	
	private Spinner FactureList;
	private Spinner UnitList;
	private TableLayout unitResultTable;	
	private DialogFragment picker;	
	private TextView currentDateView;	
	private String BillPicturePath;	
	private String currentDate;	
	private TextView unitResult;
	private EditText unitMetic;
	private EditText unitPrice;
	private EditText unitValue;	
	private ImageButton addUnit;
	private ImageButton delUnit;	
	private LinkedList<List<String>> unitStack = new LinkedList<List<String>>();	
	private List<Unit> allUnit;		
	private String readBarcode;
	private String barcode;
	
	static final int DATE_DIALOG_ID = 999;	
	public static final int REQUEST_CODE_PHOTO = 100;	
	private static final String PACKAGE_NAME = "zxing";
	private static final Pattern SEMICOLON = Pattern.compile(";");	
	private static  NewBillFragment instance;
	
	public static final NewBillFragment newInstance()
	{
		NewBillFragment f = new NewBillFragment();	
		instance = f;
	    return f;
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {				
		inflater.inflate(R.menu.main_add_facture, menu);
		super.onCreateOptionsMenu(menu,inflater);
	}	

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {		
		switch (item.getItemId()) {
	        case R.id.save_facture:
	        	if (saveFacture() == true)
	        		switchToHome();
	            return true;
	        case R.id.discard_facture:	        	
	        	switchToHome();
	            return true;
    	}			
		return super.onOptionsItemSelected(item);
	}
	
	public void switchToHome() {		
		Fragment fragment = null;
		fragment = new HomeFragment();
		FragmentManager fragmentManager = getFragmentManager();
		fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();
		fragmentManager.invalidateOptionsMenu();		
		InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
	    View view = getActivity().getCurrentFocus();
	    if(view==null)
	        return;
	    inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);	
	}
	
	public void alert(String message) {
		new AlertDialog.Builder(getActivity())
        .setIcon(android.R.drawable.ic_dialog_alert)	        
        .setMessage(message)
        .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) { }

        })  
        .show();
	}
	
	public Boolean saveFacture() {		
		
		if (GlobalParams.getInstance().billdatasource.getBill(newBillName.getText().toString()) == null && FactureList.getSelectedItem() != null)
		{		
			String factureName = FactureList.getSelectedItem().toString();		
			String billName = newBillName.getText().toString();
			String billDescription = newBillDescription.getText().toString();			
			Double billPrice = null;
			String billPriceS = newBillPrice.getText().toString();
			
			if (billPriceS.equals("")){	
				
				alert(getResources().getString(R.string.new_bill_price_empty));	
				return false;		
			}
			
			try {
				billPrice= Double.parseDouble(billPriceS);
			} catch (NumberFormatException ex) {
			}
			
			Bill newBill = new Bill();
			newBill.setName(billName);
			newBill.setDescription(billDescription);
			newBill.setPrice(billPrice);
			newBill.setFactureId(GlobalParams.getInstance().facturedatasource.getFacture(factureName).getId());	
			//Log.d(TAG, "Current date for new bill is :" + currentDateView.getText().toString());		
			newBill.setDate(currentDateView.getText().toString());				
			newBill.setPicturePath(BillPicturePath);			
			//Log.d(TAG, "PATH TO PICTURE = " + BillPicturePath);	
			GlobalParams.getInstance().billdatasource.createBill(newBill);		
			//Log.d(TAG, "new bill name = "  + billName +  " facture ID = " + newBill.getFactureId());
					
			if (allUnit.size()>0) {				
				for (List<String> st : unitStack) {		
					Unit newUnit = new Unit();
					newUnit.setName(st.get(0));						
					try {
						newUnit.setPrice(Double.parseDouble(st.get(1)));			
					}catch (NumberFormatException e) {}
											
					newUnit.setMetric(st.get(2));					
					try {
						newUnit.setValue(Double.parseDouble(st.get(3)));			
					}
					catch (NumberFormatException e) {
						Log.d("Double error", "I can not attach value to unit");
					}					
					Bill tmpBill = GlobalParams.getInstance().billdatasource.getBill(billName);
					//Log.d(TAG, "BILL ID = " + tmpBill.getId());
					newUnit.setBillID(tmpBill.getId());					
					GlobalParams.getInstance().unitdatasource.createUnit(newUnit);
				}	
			}
			return true;		
		}
		else {
			alert(getResources().getString(R.string.new_bill_name_exsist));						
			return false;			
		}
	}
	
	public void cleanFacture() {		
		Log.d(TAG, "discard facute");	
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		
		Log.d(TAG, "Fragment New Bill");
		final View rootView = inflater.inflate(R.layout.fragment_newbill, container, false);		
		setHasOptionsMenu(true);
		FactureList = (Spinner) rootView.findViewById(R.id.exsist_facture_list);
		UnitList = (Spinner) rootView.findViewById(R.id.unitlist);
		currentDateView =  (TextView)  rootView.findViewById(R.id.new_bill_current_date);
		unitResultTable = (TableLayout)  rootView.findViewById(R.id.table_units_result);	
		unitMetic = (EditText) rootView.findViewById(R.id.unit_metric_value);
		unitPrice = (EditText) rootView.findViewById(R.id.unit_price_value);
		unitValue = (EditText) rootView.findViewById(R.id.unit_value_value);	
		addUnit = (ImageButton) rootView.findViewById(R.id.add_units);
		delUnit = (ImageButton) rootView.findViewById(R.id.delete_units);		
		//currentDateView = new TextView(getActivity());	

		newBillPrice = (EditText) rootView.findViewById(R.id.new_bill_price);
		newBillTakePhoto = (ImageButton) rootView.findViewById(R.id.new_bill_takephoto);
		newBillDatepicker = (ImageButton) rootView.findViewById(R.id.new_bill_datepicker);			
		newBillBarcode  = (ImageButton) rootView.findViewById(R.id.new_bill_barcode);
		newBillName = (EditText) rootView.findViewById(R.id.new_bill_name);
		newBillDescription = (EditText) rootView.findViewById(R.id.new_bill_description);		
		setDate();		

		List<Facture> allF = GlobalParams.getInstance().facturedatasource.getAllFactures();
		List<String> factureName = new ArrayList<String>();		
		for (int i=0;  i<allF.size() ; i++)
			factureName.add(allF.get(i).getName());
		
		String[] values =  factureName.toArray(new String[factureName.size()]);
		
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, values);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		
		FactureList.setAdapter(adapter);		
		FactureList.setOnItemSelectedListener(new OnItemSelectedListener() {			
			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {	
				
						Calendar c = Calendar.getInstance();		
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
						String formattedDate = sdf.format(c.getTime());    
						currentDate = formattedDate;			
						currentDateView.setText(currentDate);
						newBillName.setText(FactureList.getSelectedItem().toString() + "_" + sdf.format(c.getTime()));
						
						//Set units for facture
						Facture tmpFacture =  GlobalParams.getInstance().facturedatasource.getFacture(FactureList.getSelectedItem().toString());						
						allUnit = GlobalParams.getInstance().unitdatasource.getAllUnitForFacture(tmpFacture.getId());
						List<String> unitNames = new ArrayList<String>();
						
						if (allUnit.size()>0 ){
							
							LinearLayout layout = (LinearLayout) rootView.findViewById(R.id.units_layout);
							layout.setVisibility(View.VISIBLE);
						
							for (int i=0;  i<allUnit.size() ; i++)
								unitNames.add(allUnit.get(i).getName());
						
							String[] valuesUnit =  unitNames.toArray(new String[unitNames.size()]);		
						
						
							ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, valuesUnit);
							adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
							
							unitMetic.setText("");
							unitPrice.setText("");
							unitValue.setText("");
							
							UnitList.setAdapter(adapter1);
							UnitList.setOnItemSelectedListener(new OnItemSelectedListener() {	
								
								@Override
								public void onItemSelected(AdapterView<?> parent, View view,
										int position, long id) {								
											
											unitMetic.setText("");
											unitPrice.setText("");
											unitValue.setText("");
									
											if (allUnit.size()>0){
												Unit newUnit = allUnit.get(position);
												unitMetic.setText(newUnit.getMetric()); 
												unitPrice.setText(newUnit.getPrice().toString());
											}						
										}
								
								@Override
								public void onNothingSelected(AdapterView<?> parent) {}			
							});
						
						}
						else {
							
							// units should be invisible
							LinearLayout layout = (LinearLayout) rootView.findViewById(R.id.units_layout);
							layout.setVisibility(View.GONE);
							
							
						}
					}
			@Override
			public void onNothingSelected(AdapterView<?> parent) {}			
		});
		
		addUnit.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				
				if (UnitList.getAdapter().getCount()>0){
					String name = UnitList.getSelectedItem().toString();
					String price = unitPrice.getText().toString();
					String metric = unitMetic.getText().toString();
					String value = unitValue.getText().toString();
					
					List<String> unitList = new ArrayList<String>();
					unitList.add(name);
					unitList.add(price);
					unitList.add(metric);
					unitList.add(value);
					
					if (price.length()>0 && value.length()>0)				
						unitStack.addLast(unitList);
					
					printStackToTextView();
				}
			}
		});
		
		
		delUnit.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {
				if (unitStack.size()>0)
					unitStack.removeLast();				
				printStackToTextView();				
			}
		});
		
		

		getActivity().showDialog(DATE_DIALOG_ID);
		newBillDatepicker.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if (FactureList.getCount() > 0 && FactureList.getSelectedItem().toString()!= null) {
					picker = new NewBillDateDialog(FactureList.getSelectedItem().toString(),currentDateView,newBillName);
					picker.show(getFragmentManager(), "datePicker");
				}
			}
		});
		
		newBillTakePhoto.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				
				takePhoto();
			}
		});
		
		newBillBarcode.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
					
				  if (readBarcode != null && readBarcode.length()>0)
					  showBarcodeTemplates("",true);
				  else {					
					  IntentIntegrator integrator = new IntentIntegratorV30(instance);				
				      integrator.addExtra("SCAN_WIDTH", 800);
				      integrator.addExtra("SCAN_HEIGHT", 200);
				      integrator.addExtra("RESULT_DISPLAY_DURATION_MS", 3000L);
				      integrator.addExtra("PROMPT_MESSAGE", "Custom prompt to scan a product");
				      integrator.initiateScan(IntentIntegrator.PRODUCT_CODE_TYPES);
				  }
				
			}
		});

		return rootView;	
		
	}
	
	public void setDate() {
		//Calendar c = Calendar.getInstance();		
		//SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		//String formattedDate = sdf.format(c.getTime());  
		//currentDate = formattedDate;
		//currentDateView.setText(currentDate);
	}
		
	 private String getMonthForInt(int num) {
	        String month = "wrong";
	        DateFormatSymbols dfs = new DateFormatSymbols();
	        String[] months = dfs.getMonths();
	        if (num >= 0 && num <= 11 ) {
	            month = months[num];
	        }
	        return month;
	}
	
	public void takePhoto() {
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");       
        startActivityForResult(intent, REQUEST_CODE_PHOTO);
    }
	
	private void showDialogBarcode(String title, CharSequence message) {
		Log.d(TAG, "Title = " + title + " Message " +  message);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(title);
        builder.setMessage(message);
        builder.setPositiveButton("OK", null);
        builder.show();
    }
	
	public void showBarcodeTemplates(String message, Boolean ifArleadyRead) {

		if (ifArleadyRead==false) {
			String[] r =  message.split("\n");
	    	String[] r2 = r[1].split(":");
	    	readBarcode = r2[1];	    
		}
		
    	
    	final Dialog dialog = new Dialog(getActivity());
		dialog.setContentView(R.layout.template_barcode_dialog);
		dialog.setTitle(getResources().getString(R.string.new_template_choose));
		
		final Spinner templates = (Spinner)  dialog.findViewById(R.id.template_list);	

		Button confirm = (Button) dialog.findViewById(R.id.confirm);	
		final Button addNewTemplate = (Button) dialog.findViewById(R.id.add_new_template);
		
		Button scanBarcode = (Button) dialog.findViewById(R.id.scan_again);
		
		List<TemplateBarcode> templatesList = GlobalParams.getInstance().templatedatasource.getAllTemplateBarcodes();	
		List<String> templatesName = new ArrayList<String>();
		
		final String factureName = FactureList.getSelectedItem().toString();
		Facture facture = GlobalParams.getInstance().facturedatasource.getFacture(factureName);
		

		templatesName.add(getResources().getString(R.string.new_template_new));							
		
		if (templatesList != null)
			for(int i =0; i<templatesList.size();i++) {
				templatesName.add(templatesList.get(i).getName());							
		}

		String[] values = templatesName.toArray(new String[templatesName.size()]);						
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, values);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		templates.setAdapter(adapter);							
		TemplateBarcode t = GlobalParams.getInstance().templatedatasource.getTemplateBarcode(facture.getTemplate_ID());
		
		if ( t!= null ) {
			int index = 0;
	        for (int i=0;i<templatesName.size();i++){					        	
	            if (templatesName.get(i).equals(t.getName())){
	                index = i;
	            }
	        }					       						
			templates.setSelection(index);
			
		}
		
		
		
		templates.setOnItemSelectedListener(new OnItemSelectedListener() {			
			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {	
				
					String name =  parent.getItemAtPosition(position).toString();
					if (name.equals(getResources().getString(R.string.new_template_new)))
						addNewTemplate.setText(getResources().getString(R.string.new_template));
					else
						addNewTemplate.setText(getResources().getString(R.string.edit_template));
					
					
					TemplateBarcode template = GlobalParams.getInstance().templatedatasource.getTemplateBarcode(name);
					if (template!=null)
					{
						GlobalParams.getInstance().barcodeStartIndex = template.getPrefix();
						GlobalParams.getInstance().barcodeEndIndex = template.getSuffix();
						if (position != 0) {
							Facture f = GlobalParams.getInstance().facturedatasource.getFacture(factureName);
							f.setTemplate_ID(template.getId());							
							GlobalParams.getInstance().facturedatasource.modifyFactue(f);
						}
					}
						
						
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {}
		});
		
		confirm.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {			
				
            	parseBarcode(readBarcode);
				dialog.dismiss();
			
			}
			
		});
		
		addNewTemplate.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				
				Intent intent = new Intent(getActivity(), AddNewTemplate.class);								
				String name = templates.getSelectedItem().toString();
				//Log.d(TAG, "Template name " + name);
				intent.putExtra("TemplateName", name);
				startActivity(intent);
				dialog.dismiss();
			
			}
			
		});
		
		scanBarcode.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				
				IntentIntegrator integrator = new IntentIntegratorV30(instance);				
				integrator.addExtra("SCAN_WIDTH", 800);
				integrator.addExtra("SCAN_HEIGHT", 200);
				integrator.addExtra("RESULT_DISPLAY_DURATION_MS", 3000L);
				integrator.addExtra("PROMPT_MESSAGE", "Custom prompt to scan a product");
				integrator.initiateScan(IntentIntegrator.PRODUCT_CODE_TYPES);
				dialog.dismiss();
			
			}
			
		});
		
		dialog.show();
		
	}
	

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    	
        Log.d(TAG,"requestCode  = " + requestCode + "resultCode = " +  resultCode);    	
        super.onActivityResult(requestCode, resultCode, data); 
        
        if (requestCode == REQUEST_CODE_PHOTO){   
        	if (resultCode == getActivity().RESULT_OK) {
	        	String[] projection = { MediaStore.Images.Media.DATA };
	            Cursor cursor = getActivity().managedQuery( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,  projection, null, null, null);
	            int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	            cursor.moveToLast();
	            BillPicturePath = cursor.getString(column_index_data);
	            BillPicturePath =  moveFile(BillPicturePath, GlobalParams.getInstance().pathToExternalDir);                
	            Log.d(TAG,"PATH = " + BillPicturePath);                
	            return;
        	}	
        	
        	
        }        
        else if (requestCode ==IntentIntegrator.REQUEST_CODE ) {
        	
        	final IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
	       	if (result != null) {
	                String contents = result.getContents();
	                if (contents != null) { 
	                	
	                	showBarcodeTemplates(result.toString(),false);

	                } else {
	                	showDialogBarcode("result_failed", "You do not read barcode");
	                }
	        }     
        	
        }
        
        
      
  
    }
    
    private void parseBarcode(String result) {
		String price = "";
		for(int i=GlobalParams.getInstance().barcodeStartIndex ; i < GlobalParams.getInstance().barcodeEndIndex; i++)
		{			
			price += result.charAt(i);
		}
		Double newPrice = Double.parseDouble(price);
		newPrice /= 100;
		
		newBillPrice.setText(newPrice.toString());
		
	}

	public void printStackToTextView() {
    	createTableUnitResult();	
	
	}
    
    public void createTableUnitResult() {
    	
    	unitResultTable.removeAllViews();

	 	for (List<String> st : unitStack) {	
	 		
	 		TableRow row = new TableRow(getActivity());

		    TextView unitName = new TextView(getActivity());
		    TextView unitPrice = new TextView(getActivity());
		    TextView unitMetric = new TextView(getActivity());
		    TextView unitValue = new TextView(getActivity());
		    
		    unitName.setText(st.get(0));
		    unitName.setBackgroundResource(R.drawable.cell_shape);
		    
		    unitPrice.setText(st.get(1));
		    unitPrice.setBackgroundResource(R.drawable.cell_shape);
		    
		    unitMetric.setText(st.get(2));
		    unitMetric.setBackgroundResource(R.drawable.cell_shape);
		   
		    unitValue.setText(st.get(3));
		    unitValue.setBackgroundResource(R.drawable.cell_shape);
		   
		    row.addView(unitName);
		    row.addView(unitPrice);
		    row.addView(unitMetric);
		    row.addView(unitValue);
		    
		    unitResultTable.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
			
	 	}

    }
	
    
private String moveFile(String source, String dest) {
		
		Log.d("MOVEFILE", "Source "+  source + " dest " +  dest);
		
		InputStream inStream = null;
		OutputStream outStream = null;
	 
    	try{
		
			File afile =new File(source);
		    File bfile =new File(dest + File.separator + afile.getName());
	
		    inStream = new FileInputStream(afile);
		    outStream = new FileOutputStream(bfile);
	
		    byte[] buffer = new byte[1024];
	
		    int length;
		    //copy the file content in bytes 
		    while ((length = inStream.read(buffer)) > 0){
	
		    	outStream.write(buffer, 0, length);
	
		    }
	
		    inStream.close();
		    outStream.close();
	
		    //delete the original file
		    afile.delete();
	
		   // System.out.println("File is copied successful!");
		    return bfile.getAbsolutePath();
		    
		    
		}catch(IOException e){
		    e.printStackTrace();
		}
		return source;	
    	
    	
    	
		
		
	}
		
    
    
}

	
	